<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow: Todo List</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow<span id="projectnumber">&#160;2.0.0</span>
   </div>
   <div id="projectbrief">Flow project: Public API.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

</div><!-- top -->
<div><div class="header">
  <div class="headertitle"><div class="title">Todo List </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><dl class="reflist">
<dt>Namespace <a class="el" href="namespaceflow.html">flow</a>  </dt>
<dd><p class="startdd"><a class="anchor" id="_todo000012"></a>As of this writing the <em>exact</em> nature of where the project will permanently reside (and who will maintain it vs. use it) is in flux. Therefore for now I have removed the section covering certain topics and replaced it with the to-do you're reading. This should be undone when things settle down (obviously ensuring the brought-back section is made accurate). The topics to cover: <code>"@author"</code> (including contact info); GitHub/other address indicating where to browse the project source; link(s) to the latest auto-generated web docs (if any); a section on the history of the project; and licensing info (if deemed needed) or pointer to it. (Reminder: Also update any similar sections of the historically significant <a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">net_flow::Node</a> doc header.)</p>
<p class="enddd"><a class="anchor" id="_todo000013"></a>Since Flow gained its first users beyond the original author, some Flow-adjacent code has been written from which Flow can benefit, including a potential <code>io</code> module/namespace for general networking/local I/O. (Flow itself continued to be developed, but some features were added elsewhere for expediency; this is a reminder to factor them out into Flow for the benefit of all.) Some features to migrate here might be: boost.asio extensions to UDP receive APIs to obtain receipt time stamps and destination IP (<code>recvmsg()</code> with ancillary data extensions) and to receive multiple datagrams in one call (<code>recvmmsg()</code>); boost.asio-adjacent facility to add custom socket options similarly to how boost.asio does it internally; boost.asio support for (local) transmission of native socket handles and security data over stream sockets (<code>SCM_RIGHTS</code>, etc.). </p>
</dd>
<dt>Member <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#ac6b98b440d52c079c22d7972c9b12e1b">flow::async::Concurrent_task_loop::schedule_from_now</a>  (const Fine_duration &amp;from_now, Scheduled_task &amp;&amp;task)=0</dt>
<dd><a class="anchor" id="_todo000004"></a>Deal with the scheduled-tasks-affected-from-outside-loop corner case of the <code>Concurrent_task_loop::schedule_*()</code> APIs. Perhaps add <code>bool in_loop_use_only</code> arg which, if <code>false</code>, will always disable the <code>single_threaded</code> optimization internally. At this time it always enables it if <code><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#a131335863b19446dbc349de181d4b5a1" title="How many threads does start() start?">n_threads()</a> == 1</code> which will cause thread un-safety if the returned handle is touched from outside an in-loop task. <code>void</code> versions of the <code>schedule_*()</code> APIs should be added which would lack this, as in that case there is no handle to misuse outside the loop. </dd>
<dt>Member <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#afff5e62840791b309e178c5ddc26e594">flow::async::Concurrent_task_loop::start</a>  (Task &amp;&amp;init_task_or_empty=<a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72" title="Short-hand for a task that can be posted for execution by a Concurrent_task_loop or flow::util::Task_...">Task()</a>, const Thread_init_func &amp;thread_init_func_or_empty=<a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#aa164fb1fe1b3d7fce0de0174d77ea396" title="Short-hand for the thread-initializer-function optional arg type to start().">Thread_init_func()</a>)=0</dt>
<dd><a class="anchor" id="_todo000002"></a><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#afff5e62840791b309e178c5ddc26e594" title="Starts all threads in the thread pool; any queued post()ed (and similar) tasks may begin executing im...">Concurrent_task_loop::start()</a> has an optional thread-initializer-function arg; it could be reasonable to ass a thread-finalizer-function arg symmetrically. As of this writing there is no use case, but it's certainly conceivable. </dd>
<dt>Member <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#aadadb5b8b6c40ddc86c205de1b8f25b1">flow::async::Concurrent_task_loop::stop</a>  ()=0</dt>
<dd><a class="anchor" id="_todo000003"></a>boost.asio has advanced features that might help to mark certain tasks as "must-run if already queued, even
if one `stop()`s"; consider providing user-friendly access to these features, perhaps in the context of the existing <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#aadadb5b8b6c40ddc86c205de1b8f25b1" title="Waits for any ongoing task(s)/completion handler(s) to return; then prevents any further-queued such ...">Concurrent_task_loop::stop()</a> API. These features are documented as of this writing at least in the <code>io_context</code> doc page.  </dd>
<dt>Class <a class="el" href="classflow_1_1async_1_1Cross__thread__task__loop.html">flow::async::Cross_thread_task_loop</a>  </dt>
<dd><a class="anchor" id="_todo000006"></a>Add dynamic configurability of low-level thread/core behavior of <a class="el" href="classflow_1_1async_1_1Cross__thread__task__loop.html" title="Concrete Concurrent_task_loop that is able to efficiently schedule Tasks within a given Op to execute...">Cross_thread_task_loop</a>, <a class="el" href="classflow_1_1async_1_1Segregated__thread__task__loop.html" title="Concrete Concurrent_task_loop that uses the legacy pin-Tasks-within-1-Op-to-1-thread method of achiev...">Segregated_thread_task_loop</a>, and the <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> interface generally, as these parameters (including <code>n_threads_or_zero</code>, <code>est_hw_core_sharing_helps_algo</code>, <code>est_hw_core_pinning_helps_algo</code>) can only be set at construction time even though <a class="el" href="classflow_1_1async_1_1Cross__thread__task__loop.html#a5705e34163dec8463a30361bdb2fa83f" title="Implements superclass API.">start()</a> and <a class="el" href="classflow_1_1async_1_1Cross__thread__task__loop.html#aa0f53f269524b701b23237766f79df2d" title="Implements superclass API.">stop()</a> can be invoked anytime. For instance a non-<code>virtual</code> <code>configure()</code> method could be added to each <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> subclass, potentially with different signatures. Note, also, that the decision to have <a class="el" href="classflow_1_1async_1_1Cross__thread__task__loop.html#aa0f53f269524b701b23237766f79df2d" title="Implements superclass API.">stop()</a> exit the actual threads, in addition to making some things easier to code/reason about internally, is also more amenable to these dynamic changes &ndash; messing with threading behavior dynamically is easier if one can exit and re-spawn the thread pool. </dd>
<dt>Member <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a57525f29ac96f4edd56c951e7d7c7b25">flow::async::S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION</a>  </dt>
<dd><a class="anchor" id="_todo000001"></a>Much like the promise/future mechanism provides optional timed wait functionality, it might make sense to provide the API ability to set an optional time limit for any wait invoked by <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a57525f29ac96f4edd56c951e7d7c7b25" title="Same as Synchronicity::S_ASYNC but the posting routine then waits as long as necessary for the given ...">Synchronicity::S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION</a> or <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485ae9a9ae292ea3fbbe3b313348dcec0846" title="Same as Synchronicity::S_ASYNC but the posting routine then waits as long as necessary for the given ...">Synchronicity::S_ASYNC_AND_AWAIT_CONCURRENT_START</a>. Probably best to add this only once a need clearly arises though.  </dd>
<dt>Member <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a2669021fe545a05ced370f09ce794f52">flow::async::Single_thread_task_loop::schedule_from_now</a>  (const Fine_duration &amp;from_now, Scheduled_task &amp;&amp;task)</dt>
<dd><a class="anchor" id="_todo000005"></a>Deal with the scheduled-tasks-affected-from-outside-loop corner case of the <code>Single_thread_task_loop::schedule_*()</code> APIs. Perhaps add <code>bool in_loop_use_only</code> arg which, if <code>false</code>, will always disable the <code>single_threaded</code> optimization internally. At this time it always enables it which will cause thread un-safety if the returned handle is touched from outside an in-loop task. <code>void</code> versions of the <code>schedule_*()</code> APIs should be added which would lack this, as in that case there is no handle to misuse outside the loop. </dd>
<dt>Class <a class="el" href="classflow_1_1cfg_1_1Config__manager.html">flow::cfg::Config_manager&lt; S_d_value_set &gt;</a>  </dt>
<dd><a class="anchor" id="_todo000007"></a>Dynamic config support lacks crash rejection; though these features should be an incremental improvement around the existing code. By crash rejection I mean something like: config file X comes in; we rename it to X.unparsed; we try to parse it; program crashes &ndash; versus it's fine, so we rename it X.parsed, and next time X.parsed is what we presumably-safely parse after any restart. Similarly invalid config may not cause a crash but still shouldn't be repeatedly re-parsed (etc.). Exact design TBD and will be informed by previous work on other projects (by echan and ygoldfel at least). </dd>
<dt>Member <a class="el" href="classflow_1_1cfg_1_1Config__manager.html#a22bfec8082d0c7b5dff9ee7e98865707">flow::cfg::Config_manager&lt; S_d_value_set &gt;::apply_static</a>  (const fs::path &amp;static_cfg_path, const typename <a class="el" href="structflow_1_1cfg_1_1Final__validator__func.html#a5475ab0b6e93f2ccded2aa8690ace0a4" title="Short-hand for a function that takes a parsed config set (meaning all values are individually OK) and...">Final_validator_func&lt; Value_set &gt;::Type</a> &amp;... final_validator_func, bool commit=true)</dt>
<dd><a class="anchor" id="_todo000008"></a>Add support for command line as a config source in addition to file(s), for static config in <a class="el" href="classflow_1_1cfg_1_1Config__manager.html" title="Manages a config setup, intended for a single daemon process, by maintaining 1 or more set(s) of stat...">cfg::Config_manager</a> and <a class="el" href="classflow_1_1cfg_1_1Static__config__manager.html" title="A Config_manager-related adapter-style class that manages a simple config setup involving a single (t...">cfg::Static_config_manager</a>. </dd>
<dt>Class <a class="el" href="classflow_1_1cfg_1_1Dynamic__cfg__context.html">flow::cfg::Dynamic_cfg_context&lt; Root, Target, Target_ptr &gt;</a>  </dt>
<dd><a class="anchor" id="_todo000009"></a><a class="el" href="classflow_1_1cfg_1_1Dynamic__cfg__context.html" title="Class which facilitates managing access to a dynamic configuration.">flow::cfg::Dynamic_cfg_context</a> <code>Target_ptr</code> is deprecated and shall be always left at its default value in future code; eventually remove it entirely and hard-code the default value internally.  </dd>
<dt>Class <a class="el" href="classflow_1_1cfg_1_1Option__set.html">flow::cfg::Option_set&lt; Value_set &gt;</a>  </dt>
<dd><a class="anchor" id="_todo000010"></a>Add individual-option-changed detection API(s) in addition to the existing <a class="el" href="classflow_1_1cfg_1_1Option__set.html" title="The core config-parsing facility, which builds parsing/comparison/output capabilities on top of a giv...">Option_set</a> overall-value-set-changed detection API. This is contingent on a use case needing it. The existing code already detects this internally and logs a message for each changed option (in <a class="el" href="classflow_1_1cfg_1_1Option__set.html#aa1f780bfd3a5ff07ade1e36785e28f49" title="In PARSING state enters CANONICAL state, finalizing values() from values_candidate().">canonicalize_candidate()</a>). </dd>
<dt>Member <a class="el" href="classflow_1_1cfg_1_1Static__config__manager.html#aacacd2c0eddaf68d0dc5e0c1407572f5">flow::cfg::Static_config_manager&lt; Value_set &gt;::apply</a>  (const fs::path &amp;cfg_path, const typename <a class="el" href="structflow_1_1cfg_1_1Final__validator__func.html#a5475ab0b6e93f2ccded2aa8690ace0a4" title="Short-hand for a function that takes a parsed config set (meaning all values are individually OK) and...">Final_validator_func&lt; Value_set &gt;::Type</a> &amp;final_validator_func)</dt>
<dd><a class="anchor" id="_todo000011"></a>Add support for command line as a config source in addition to file(s), for static config in <a class="el" href="classflow_1_1cfg_1_1Config__manager.html" title="Manages a config setup, intended for a single daemon process, by maintaining 1 or more set(s) of stat...">cfg::Config_manager</a>. </dd>
<dt>Class <a class="el" href="classflow_1_1log_1_1Async__file__logger.html">flow::log::Async_file_logger</a>  </dt>
<dd><a class="anchor" id="_todo000014"></a>Lacking feature: Compress-as-you-log in <a class="el" href="classflow_1_1log_1_1Async__file__logger.html" title="An implementation of Logger that logs messages to a given file-system path but never blocks any loggi...">Async_file_logger</a>. So, optionally, when characters are actually written out to file-system, gzip/zip/whatever them instead of writing plain text. (This is possible at least for gzip.) Background: It is common-place to compress a log file after it has been rotated (e.g., around rotation time: F.log.1.gz -&gt; F.log.2.gz, F.log -&gt; F.log.1 -&gt; F.log.1.gz). It is more space-efficient (at least), however, to write to F.log.gz directly already in compressed form; then rotation requires only renaming (e.g.: F.log.1.gz -&gt; F.log.2.gz, F.log.gz [already gzipped from the start] -&gt; F.log.1.gz). </dd>
<dt>Member <a class="el" href="classflow_1_1log_1_1Async__file__logger.html#aec2b1796c81b020cacea493e21e19562">flow::log::Async_file_logger::Async_file_logger</a>  (<a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> *backup_logger_ptr, <a class="el" href="classflow_1_1log_1_1Config.html" title="Class used to configure the filtering and logging behavior of Loggers; its use in your custom Loggers...">Config</a> *config, const fs::path &amp;log_path, bool capture_rotate_signals_internally)</dt>
<dd><a class="anchor" id="_todo000015"></a>Consider adding <a class="el" href="classflow_1_1log_1_1Async__file__logger.html" title="An implementation of Logger that logs messages to a given file-system path but never blocks any loggi...">Async_file_logger</a> constructor option to overwrite the file instead of appending. </dd>
<dt>Member <a class="el" href="classflow_1_1log_1_1Async__file__logger.html#aaaf956d63042cbc0800680996adabfa2">flow::log::Async_file_logger::log_flush_and_reopen</a>  (bool async=true)</dt>
<dd><a class="anchor" id="_todo000016"></a><code>Async_file_logger::log_flush_and_reopen(true)</code> is great for flushing, such as in an abort-signal handler, but providing just the flushing part without the reopening might be useful. At the moment we've left it this way, due to the vague feeling that closing the file upon flushing it is somehow more final and thus safer (in terms of accomplishing its goal) in an abort-signal scenario. Feelings aren't very scientific though. </dd>
<dt>Class <a class="el" href="classflow_1_1log_1_1Config.html">flow::log::Config</a>  </dt>
<dd><a class="anchor" id="_todo000018"></a>Class <a class="el" href="classflow_1_1log_1_1Config.html" title="Class used to configure the filtering and logging behavior of Loggers; its use in your custom Loggers...">Config</a> doc header is wordy and might be hard to follow; rewrite for clarity/flow/size. </dd>
<dt>Member <a class="el" href="classflow_1_1log_1_1Config.html#ab067e9e513530e7484a30f568b1e11d5">flow::log::Config::Config</a>  (<a class="el" href="classflow_1_1log_1_1Config.html" title="Class used to configure the filtering and logging behavior of Loggers; its use in your custom Loggers...">Config</a> &amp;&amp;)=delete</dt>
<dd><a class="anchor" id="_todo000019"></a>Reconsider providing a <a class="el" href="classflow_1_1log_1_1Config.html" title="Class used to configure the filtering and logging behavior of Loggers; its use in your custom Loggers...">Config</a> move constructor. I just didn't need to deal with it.  </dd>
<dt>Member <a class="el" href="classflow_1_1log_1_1Config.html#a60c9a16ebb764e4fcc4208a55c2e785d">flow::log::Config::operator=</a>  (const <a class="el" href="classflow_1_1log_1_1Config.html" title="Class used to configure the filtering and logging behavior of Loggers; its use in your custom Loggers...">Config</a> &amp;)=delete</dt>
<dd><a class="anchor" id="_todo000020"></a>Reconsider providing a <a class="el" href="classflow_1_1log_1_1Config.html" title="Class used to configure the filtering and logging behavior of Loggers; its use in your custom Loggers...">Config</a> copy assignment. I just didn't need to deal with it.  </dd>
<dt>Member <a class="el" href="classflow_1_1log_1_1Config.html#ac8a787b8026d84814bf4edcc91432447">flow::log::Config::operator=</a>  (<a class="el" href="classflow_1_1log_1_1Config.html" title="Class used to configure the filtering and logging behavior of Loggers; its use in your custom Loggers...">Config</a> &amp;&amp;)=delete</dt>
<dd><a class="anchor" id="_todo000021"></a>Reconsider providing a <a class="el" href="classflow_1_1log_1_1Config.html" title="Class used to configure the filtering and logging behavior of Loggers; its use in your custom Loggers...">Config</a> move assignment. I just didn't need to deal with it.  </dd>
<dt>Member <a class="el" href="classflow_1_1log_1_1Logger.html#a1ea9da10a13d3b422ba7162a13d7eeb1">flow::log::Logger::set_thread_info</a>  (std::string *call_thread_nickname, <a class="el" href="namespaceflow_1_1util.html#a0a4e7b2d3107bd630e0dc0c0b8f2e4de" title="Short-hand for an OS-provided ID of a util::Thread.">flow::util::Thread_id</a> *call_thread_id)</dt>
<dd><a class="anchor" id="_todo000026"></a>It would be more consistent to rename <a class="el" href="classflow_1_1log_1_1Logger.html#a1ea9da10a13d3b422ba7162a13d7eeb1" title="Same as set_thread_info_in_msg_metadata() but targets the given two variables as opposed to a Msg_met...">set_thread_info()</a> to this_thread_set_info(), since it operates in thread-local fashion. This was a naming convention oversight. </dd>
<dt>Member <a class="el" href="classflow_1_1log_1_1Logger.html#a2d1a0283764e5f85abf00c7cee4c4e19">flow::log::Logger::set_thread_info_in_msg_metadata</a>  (<a class="el" href="structflow_1_1log_1_1Msg__metadata.html" title="Simple data store containing all of the information generated at every logging call site by flow::log...">Msg_metadata</a> *msg_metadata)</dt>
<dd><a class="anchor" id="_todo000025"></a>It would be more consistent to rename <a class="el" href="classflow_1_1log_1_1Logger.html#a2d1a0283764e5f85abf00c7cee4c4e19" title="Loads msg_metadata-&gt;m_call_thread_nickname (if set) or else msg_metadata-&gt;m_call_thread_id,...">set_thread_info_in_msg_metadata()</a> to this_thread_set_info_in_msg_metadata(), since it operates in thread-local fashion. This was a naming convention oversight. </dd>
<dt>Member <a class="el" href="classflow_1_1log_1_1Logger.html#a5600c71ccaa294650c7d34b596d90bf5">flow::log::Logger::this_thread_set_logged_nickname</a>  (<a class="el" href="namespaceflow_1_1util.html#ae4dc52186797094b3040379ff19124c9" title="Commonly used char-based Basic_string_view. See its doc header.">util::String_view</a> thread_nickname=<a class="el" href="namespaceflow_1_1util.html#ae4dc52186797094b3040379ff19124c9" title="Commonly used char-based Basic_string_view. See its doc header.">util::String_view()</a>, <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> *logger_ptr=0, bool also_set_os_name=true)</dt>
<dd><a class="anchor" id="_todo000024"></a><a class="el" href="classflow_1_1log_1_1Logger.html#a5600c71ccaa294650c7d34b596d90bf5" title="Sets or unsets the current thread&#39;s logging-worthy string name; optionally sets the OS thread name (s...">this_thread_set_logged_nickname()</a> could take multiple <code><a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a></code>s, since it is an app-wide function and potentially would want to be reflected in multiple loggers. It could take a pair of iterators or a container (in both cases, of template argument type). Arguably, though, this is overkill; as (1) most code paths deal with only one <code>get_logger()</code>-owning object each; (2) naming of a thread is obvious enough in subsequent logs (hence this message only calls attention to that operation plus notes the thread ID before the nickname assignment, not necessarily the most critical of information). Certainly this zero-to-one-<code><a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a></code> version must continue to be available for syntactic-sugary convenience, even if the to-do is performed.  </dd>
<dt>Class <a class="el" href="structflow_1_1log_1_1Msg__metadata.html">flow::log::Msg_metadata</a>  </dt>
<dd><a class="anchor" id="_todo000023"></a>Add support in <a class="el" href="structflow_1_1log_1_1Msg__metadata.html" title="Simple data store containing all of the information generated at every logging call site by flow::log...">Msg_metadata</a> for a message ID which could more straightforwardly help the human log reader to map a log line to the originating log call site in source code. One approach, then, might be to output that message ID when available; else output <a class="el" href="structflow_1_1log_1_1Msg__metadata.html#a5e7224fd18f1b9b2600508ac399687dd" title="Pointer/length into static-storage string that would have come from built-in __FILE__ macro which is ...">m_msg_src_file</a>, <a class="el" href="structflow_1_1log_1_1Msg__metadata.html#a2f17801fae328d1fdc070edc2578dd91" title="Copy of integer that would have come from built-in __LINE__ macro which is auto-invoked by all FLOW_L...">m_msg_src_line</a>, <a class="el" href="structflow_1_1log_1_1Msg__metadata.html#af7704a632434e7b52c43ab6047cf023b" title="Analogous to m_msg_src_file but coming from __FUNCTION__, not __FILE__. See m_msg_src_file perf notes...">m_msg_src_function</a>; or maybe both.  </dd>
<dt>Class <a class="el" href="classflow_1_1net__flow_1_1asio_1_1Node.html">flow::net_flow::asio::Node</a>  </dt>
<dd><a class="anchor" id="_todo000027"></a>To enable reactor-style <code>async_*()</code> operations, meaning waiting for readability/writability/etc. but <em>not</em> performing the actual operation before calling the user handler, we provide a <code>nullptr_t</code>-style interface; like newer boost.asio versions we should deprecate this in favor of simpler <code>async_wait()</code> APIs. This would apply to <a class="el" href="classflow_1_1net__flow_1_1asio_1_1Peer__socket.html" title="A net_flow::Peer_socket that adds integration with boost.asio.">net_flow::asio::Peer_socket</a> and <a class="el" href="classflow_1_1net__flow_1_1asio_1_1Server__socket.html" title="A net_flow::Server_socket that adds integration with boost.asio.">net_flow::asio::Server_socket</a> APIs. Similarly consider doing this for the <code>sync_*()</code> operations in the non-<code>asio</code> superclasses <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">net_flow::Peer_socket</a> and <a class="el" href="classflow_1_1net__flow_1_1Server__socket.html" title="A server socket able to listen on a single Flow port for incoming connections and return peer sockets...">net_flow::Server_socket</a>. Note that <a class="el" href="classflow_1_1net__flow_1_1Event__set.html#a43dfb881ab3a9488a6a60dd83ad21c85" title="Moves object to State::S_WAITING state, saves the given handler to be executed later (in a different,...">Event_set::async_wait()</a> and <a class="el" href="classflow_1_1net__flow_1_1Event__set.html#a133c518168fe3922ab6729a99077dd3f" title="Blocks indefinitely until one or more of the previously described events hold – or the wait is interr...">Event_set::sync_wait()</a> already exist; they are powerful but a bit complex to use in these simple situations. Hence the following hypothetical wrappers would be welcome replacements for the deprecated <code>nullptr_t</code> and "reactor-style" APIs in these classes: <code>net_flow::Peer_socket::sync_wait(Event_set::Event_type)</code>, <code>net_flow::asio::Peer_socket::async_wait(Event_set::Event_type)</code>, <code>net_flow::Server_socket::sync_wait()</code>, <code>net_flow::Server_socket::async_wait()</code>. (Timeout-arg versions would be desired also, as they exist now.) </dd>
<dt>Member <a class="el" href="classflow_1_1net__flow_1_1Event__set.html#a72b26f25a2e76e3c61b4760b59de5b25">flow::net_flow::Event_set::emit_result_sockets</a>  (Sockets *target_set, Event_type ev_type, Error_code *err_code=0)</dt>
<dd><a class="anchor" id="_todo000028"></a><a class="el" href="classflow_1_1net__flow_1_1Event__set.html#a72b26f25a2e76e3c61b4760b59de5b25" title="Gets the sockets that satisfy the condition of the given Event_type detected during the last wait.">Event_set::emit_result_sockets()</a> sets a <a class="el" href="classflow_1_1net__flow_1_1Event__set.html#a592b3ce6602051bd9994216041a3cbdc" title="A set of sockets of one type, used to communicate sets of desired and resulting events in various Eve...">Sockets</a> structure which stores <code>boost:any</code>s each of which stores either a <code><a class="el" href="classflow_1_1util_1_1Shared__ptr__alias__holder.html#aa4f1af88393042e60159a3a67f0accbc" title="Short-hand for ref-counted pointer to mutable values of type Target_type::element_type (a-la T*).">Peer_socket::Ptr</a></code> or a <code><a class="el" href="classflow_1_1util_1_1Shared__ptr__alias__holder.html#aa4f1af88393042e60159a3a67f0accbc" title="Short-hand for ref-counted pointer to mutable values of type Target_type::element_type (a-la T*).">Server_socket::Ptr</a></code>; <a class="el" href="classflow_1_1net__flow_1_1Event__set.html#a592b3ce6602051bd9994216041a3cbdc" title="A set of sockets of one type, used to communicate sets of desired and resulting events in various Eve...">Sockets</a> should be changed to store C++17 <code>std::variant</code>s. Performance, both internally and externally, would improve by using this type-safe compile-time mechanism (which is akin to <code>union</code>s but much more pleasant to use). At the time this feature was written, Flow was in C++11, so <code>variant</code>s were not available, and the author wanted to play around with <code>any</code>s instead of haxoring old-school <code>union</code>s. <code>variant</code> is much nicer, however, and the dynamic nature of <code>any</code> is entirely unnecessary here.  </dd>
<dt>Class <a class="el" href="classflow_1_1net__flow_1_1Net__env__simulator.html">flow::net_flow::Net_env_simulator</a>  </dt>
<dd><a class="anchor" id="_todo000032"></a>One thing we should probably add for a bit of realism is the following. If a loss range [A, B] is specified, an individual packet's simulated latency will be a uniformly random number in that range. Because of this there will be frequent re-ordering of packets: if range is [50, 100] ms, and we physically get packet X at time 0 and packet Y at time 5 ms, and the simulated latencies are 80, 60 ms, respectively, then Y will "arrive" 80 - 60 - 5 = 15 ms BEFORE X despite being sent earlier (assuming perfect actual network conditions under the simulation). In reality, packets aren't re-ordered all that often. So if we wanted to simulate a high latency without re-ordering, we'd have to set the range to [A, A] for some A. To avoid having to do that, we can add some internal memory into <a class="el" href="classflow_1_1net__flow_1_1Net__env__simulator.html" title="Objects of this class can be fed to Node to make it internally simulate network conditions like loss,...">Net_env_simulator</a> that would put a floor on a randomly generated latency. In the previous example, the range for packet Y would be chosen as [75, 100] (instead of [50, 100]) to guarantee that packet Y arrives at least a bit later than packet X. Of course that might skew the latency range in bursty traffic, but that might be an OK behavior. We could add a knob for how often to ignore this new logic and allow a re-ordering, so that that is also simulated.  </dd>
<dt>Class <a class="el" href="classflow_1_1net__flow_1_1Node.html">flow::net_flow::Node</a>  </dt>
<dd><p class="startdd"><a class="anchor" id="_todo000035"></a>Some of the <code>ostream&lt;&lt;</code> operators we have take <code>X*</code> instead of <code>const X&amp;</code>; this should be changed to the latter for various minor reasons and for consistency.</p>
<p class="interdd"><a class="anchor" id="_todo000034"></a><code>ostream</code> output operators for <a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">Node</a> and <a class="el" href="classflow_1_1net__flow_1_1asio_1_1Node.html" title="A subclass of net_flow::Node that adds the ability to easily and directly use net_flow sockets in gen...">asio::Node</a> should exist. Also scour through all types; possibly some others could use the same. (I have been pretty good at already implementing these as-needed for logging; but I may have "missed a spot.")</p>
<p class="interdd"><a class="anchor" id="_todo000036"></a>Actively support IPv6 and IPv4, particularly in dual-stack mode (wherein <a class="el" href="classflow_1_1net__flow_1_1Server__socket.html" title="A server socket able to listen on a single Flow port for incoming connections and return peer sockets...">net_flow::Server_socket</a> would bind to an IPv6 endpoint but accept incoming V4 and V6 connections alike). It already supports it nominally, in that one can indeed listen on either type of address and connect to either as well, but how well it works is untested, and from some outside experience it might involve some subtle provisions internally.</p>
<p class="interdd"><a class="anchor" id="_todo000037"></a>Based on some outside experience, there maybe be problems &ndash; particularly considering the to-do regarding dual-stack IPv6/v4 support &ndash; in servers listening in multiple-IP situations; make sure we support these seamlessly. For example consider a machine with a WAN IP address and a LAN (10.x.x.x) IP address (and possibly IPv6 versions of each also) that (as is typical) binds on all of them at ANY:P (where P is some port; and ANY is the IPv6 version, with dual-stack mode ensuring V4 datagrams are also received). If a client connects to a LAN IP, while in our return datagrams we set the source IP to the default, does it work? Outside experience shows it might not, depending, plus even if in our protocol it does, it might be defeated by some firewall... the point is it requires investigation (e.g., mimic TCP itself; or look into what IETF or Google QUIC does; and so on).</p>
<p class="enddd"><a class="anchor" id="_todo000033"></a><a class="el" href="namespaceflow_1_1net__flow.html" title="Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...">flow::net_flow</a> should use <a class="el" href="namespaceflow_1_1cfg.html" title="Flow module that facilitates configuring modules, such as applications and APIs, via statically and/o...">flow::cfg</a> for its socket-options mechanism. It is well suited for that purpose, and it uses some ideas from those socket-options in the first place but is generic and much more advanced. Currently <code><a class="el" href="namespaceflow_1_1net__flow.html" title="Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...">net_flow</a></code> socket-options are custom-coded from long before <a class="el" href="namespaceflow_1_1cfg.html" title="Flow module that facilitates configuring modules, such as applications and APIs, via statically and/o...">flow::cfg</a> existed. </p>
</dd>
<dt>Member <a class="el" href="classflow_1_1net__flow_1_1Node.html#a16c53c4848ea976b075a0b56f33eb118">flow::net_flow::Node::~Node</a>  () override</dt>
<dd><p class="startdd"><a class="anchor" id="_todo000039"></a>Provide another method to shut down everything gracefully? </p>
<p class="enddd"><a class="anchor" id="_todo000038"></a><a class="el" href="classflow_1_1net__flow_1_1Server__socket.html" title="A server socket able to listen on a single Flow port for incoming connections and return peer sockets...">Server_socket</a> objects closed as if by what? </p>
</dd>
<dt>Class <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html">flow::net_flow::Peer_socket</a>  </dt>
<dd><a class="anchor" id="_todo000046"></a>Closing connection considerations. May implement closing only via timeouts at first (as opposed to explicit closing). Below text refers to <code>close_final()</code> and <code>close_start()</code>, but those are just ideas and may be replaced with timeout, or nothing. At this time, the only closing supported is abrupt close due to error or abrupt close via <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#a9ab710704237f912eb219f9b8d574afc" title="Acts as if fatal error error::Code::S_USER_CLOSED_ABRUPTLY has been discovered on the connection.">close_abruptly()</a>. </dd>
<dt>Member <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#a9ab710704237f912eb219f9b8d574afc">flow::net_flow::Peer_socket::close_abruptly</a>  (Error_code *err_code=0)</dt>
<dd><p class="startdd"><a class="anchor" id="_todo000047"></a>Currently this <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#a9ab710704237f912eb219f9b8d574afc" title="Acts as if fatal error error::Code::S_USER_CLOSED_ABRUPTLY has been discovered on the connection.">close_abruptly()</a> is the only way for the user to explicitly close one specified socket. All other ways are due to error (or other side starting graceful shutdown, once we implement that). Once we implement graceful close, via <code>close_start()</code> and <code>close_final()</code>, use of <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#a9ab710704237f912eb219f9b8d574afc" title="Acts as if fatal error error::Code::S_USER_CLOSED_ABRUPTLY has been discovered on the connection.">close_abruptly()</a> should be discouraged, or it may even be deprecated (e.g., <code><a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">Node</a></code>s lack a way to initiate an abrupt close for a specific socket).</p>
<p class="enddd"><a class="anchor" id="_todo000048"></a><a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#a9ab710704237f912eb219f9b8d574afc" title="Acts as if fatal error error::Code::S_USER_CLOSED_ABRUPTLY has been discovered on the connection.">close_abruptly()</a> return <code>bool</code> (<code>false</code> on failure)? </p>
</dd>
<dt>Member <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#aad81cc16fc6f0d353fdc1379e1dd4712">flow::net_flow::Peer_socket::info</a>  () const</dt>
<dd><a class="anchor" id="_todo000050"></a>Provide a similar <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#aad81cc16fc6f0d353fdc1379e1dd4712" title="Returns a structure containing the most up-to-date stats about this connection.">info()</a> method that loads an existing structure (for structure reuse). </dd>
<dt>Member <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#ad94e37c8cca01f801f13e9e0e0bc857d">flow::net_flow::Peer_socket::options</a>  () const</dt>
<dd><a class="anchor" id="_todo000049"></a>Provide a similar <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#ad94e37c8cca01f801f13e9e0e0bc857d" title="Copies this socket&#39;s option set and returns that copy.">options()</a> method that loads an existing structure (for structure reuse). </dd>
<dt>Member <a class="el" href="structflow_1_1net__flow_1_1Peer__socket__info.html#a784bd75264e26acbccd966e48c07dab9">flow::net_flow::Peer_socket_info::m_snd_cong_ctl_in_flight_bytes</a>  </dt>
<dd><a class="anchor" id="_todo000031"></a>Does <a class="el" href="structflow_1_1net__flow_1_1Peer__socket__info.html#a784bd75264e26acbccd966e48c07dab9" title="In congestion control, the current sent data bytes that have been neither acknowledged nor considered...">m_snd_cong_ctl_in_flight_bytes</a> count data queued in the pacing module or truly In-flight data only?  </dd>
<dt>Member <a class="el" href="structflow_1_1net__flow_1_1Peer__socket__options.html#a1bdc21e84373dd96494a76f11603335e">flow::net_flow::Peer_socket_options::m_st_cong_ctl_max_cong_wnd_blocks</a>  </dt>
<dd><a class="anchor" id="_todo000045"></a>Reconsider this value after Receive window feature is implemented.  </dd>
<dt>Member <a class="el" href="structflow_1_1net__flow_1_1Peer__socket__options.html#aeaaf832a38a5e334789e81e214686ea7">flow::net_flow::Peer_socket_options::m_st_max_block_size</a>  </dt>
<dd><a class="anchor" id="_todo000044"></a>max-block-size should be dynamically determined (but overridable by this option). That is a complex topic, however, with considerations such as MTU discovery, ICMP errors, and who knows what else.  </dd>
<dt>Member <a class="el" href="classflow_1_1net__flow_1_1Peer__socket__send__stats.html#a13bf4f61554410f5dcc8928d64212e04">flow::net_flow::Peer_socket_send_stats::m_init_time</a>  </dt>
<dd><a class="anchor" id="_todo000030"></a><a class="el" href="structflow_1_1net__flow_1_1Peer__socket__receive__stats.html" title="A data store that keeps stats about the incoming direction of a Peer_socket connection to another Flo...">Peer_socket_receive_stats</a> also independently stores a similar value, so to save memory put <a class="el" href="classflow_1_1net__flow_1_1Peer__socket__send__stats.html#a13bf4f61554410f5dcc8928d64212e04" title="The time this object was created; should be about equal to when the socket was created.">m_init_time</a> elsewhere.  </dd>
<dt>Class <a class="el" href="classflow_1_1net__flow_1_1Server__socket.html">flow::net_flow::Server_socket</a>  </dt>
<dd><a class="anchor" id="_todo000056"></a>Implement <code>Server_socket::close()</code> functionality &ndash; at least the equivalent of <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#a9ab710704237f912eb219f9b8d574afc" title="Acts as if fatal error error::Code::S_USER_CLOSED_ABRUPTLY has been discovered on the connection.">Peer_socket::close_abruptly()</a>. </dd>
<dt>Member <a class="el" href="classflow_1_1net__flow_1_1Server__socket.html#aeea8554e23c8d743ca4956c772adbf24">flow::net_flow::Server_socket::accept</a>  (Error_code *err_code=0)</dt>
<dd><a class="anchor" id="_todo000057"></a>Reconsider allowing successful <a class="el" href="classflow_1_1net__flow_1_1Server__socket.html#aeea8554e23c8d743ca4956c772adbf24" title="Non-blocking accept: obtain socket for the least recently established not-yet-obtained peer connectio...">accept()</a> in <a class="el" href="classflow_1_1net__flow_1_1Server__socket.html#a8bc789b851677a47d7c0a1aa0c69a997aa27ca0689984ee6c6784a9265a678d42" title="No accept()s are or will be possible, but Node is still finishing up the closing operation.">State::S_CLOSING</a> state? </dd>
<dt>Member <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0">flow::perf::Clock_type</a>  </dt>
<dd><a class="anchor" id="_todo000060"></a>Consider adding a system-calendar-clock (a/k/a POSIX time) type to <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a>. It would be a cousin of <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a8cbf506eda585c026dfb5b72c402d342" title="Measures real time (not processor time), using the highest-resolution system clock available that gua...">Clock_type::S_REAL_HI_RES</a>. It would certainly be inferior in terms of resolution/monotonicity/etc., and one would think <code>S_REAL_HI_RES</code> would always be preferable. Nevertheless it would be interesting to "officially" see its characteristics including in particular (1) resolution and (2) its own perf cost especially vs. <code>S_REAL_HI_RES</code> which we know is quite fast itself. This may also help a certain to-do listed as of this writing in the doc header of <a class="el" href="namespaceflow_1_1log.html" title="Flow module providing logging functionality.">flow::log</a> <a class="el" href="log_8hpp.html#a5daa2b6d16edea74bb8bddc75f7fb801" title="Identical to FLOW_LOG_WITH_CHECKING() but foregoes the filter (Logger::should_log()) check.">FLOW_LOG_WITHOUT_CHECKING()</a> (the main worker bee of the log system, the one that generates each log time stamp).  </dd>
<dt>Member <a class="el" href="namespaceflow_1_1perf.html#a129032bde1082e8f2681669acf6bf03d">flow::perf::operator*=</a>  (<a class="el" href="structflow_1_1perf_1_1Duration__set.html" title="Convenience wrapper around an array&lt;Duration, N&gt;, which stores a duration for each of the N possible ...">Duration_set</a> &amp;target, uint64_t mult_scale)</dt>
<dd><a class="anchor" id="_todo000061"></a>Maybe allow <code>operator*=(Duration_set)</code> by a potentially negative number; same for division. </dd>
<dt>Member <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784">flow::perf::timed_function</a>  (Clock_type clock_type, Accumulator *accumulator, Func &amp;&amp;function)</dt>
<dd><p class="startdd"><a class="anchor" id="_todo000062"></a><a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a>, when operating on an <code>atomic&lt;duration_rep_t&gt;</code>, uses <code>+=</code> for accumulation which may be lock-free but uses strict ordering; a version that uses <code>fetch_add()</code> with relaxed ordering may be desirable for extra performance at the cost of not-always-up-to-date accumulation results in all threads. As of this writing this can be done by the user by providing a custom type that defines <code>+=</code> as explicitly using <code>fetch_add()</code> with relaxed ordering; but we could provide an API for this.</p>
<p class="enddd"><a class="anchor" id="_todo000063"></a><a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a> overload exists for a single <code>Clock_type</code>, but simultaneous multi-clock timing using the <a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601" title="Short-hand for a bit-set of N bits which represents the presence or absence of each of the N possible...">perf::Clock_types_subset</a> paradigm (as used, e.g., in <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a>) would be a useful and consistent API. E.g., one could measure user and system elapsed time simultaneously. As of this writing this only does not exist due to time constraints: a perf-niggardly version targeting one clock type was necessary. </p>
</dd>
<dt>Namespace <a class="el" href="namespaceflow_1_1util.html">flow::util</a>  </dt>
<dd><a class="anchor" id="_todo000073"></a>Since Flow gained its first users beyond the original author, some Flow-adjacent code has been written from which Flow can benefit, including additions to <a class="el" href="namespaceflow_1_1util.html" title="Flow module containing miscellaneous general-use facilities that don&#39;t fit into any other Flow module...">flow::util</a> module. (Flow itself continued to be developed, but some features were added elsewhere for expediency; this is a reminder to factor them out into Flow for the benefit of all.) Some features to migrate here might be: conversion between boost.chrono and std.chrono types; (add more here).  </dd>
<dt>Class <a class="el" href="classflow_1_1util_1_1Basic__blob.html">flow::util::Basic_blob&lt; Allocator, S_SHARING_ALLOWED &gt;</a>  </dt>
<dd><a class="anchor" id="_todo000064"></a>Write a class template, perhaps <code>Tight_blob&lt;Allocator, bool&gt;</code>, which would be identical to <a class="el" href="classflow_1_1util_1_1Basic__blob.html" title="A hand-optimized and API-tweaked replacement for vector&lt;uint8_t&gt;, i.e., buffer of bytes inside an all...">Basic_blob</a> but forego the framing features, namely <a class="el" href="classflow_1_1util_1_1Basic__blob.html#a8c04d217b83800f818c794da17dc8e4b" title="Returns number of elements stored, namely end() - begin().">size()</a> and <a class="el" href="classflow_1_1util_1_1Basic__blob.html#a64ea173065830ef1a744458a7d05b833" title="Returns the offset between begin() and the start of the internally allocated buffer.">start()</a>, thus storing only the RAII array pointer <a class="el" href="classflow_1_1util_1_1Basic__blob.html#a4581e779dace3d64fe4098eb0a7dbeb2" title="Equivalent to begin().">data()</a> and <a class="el" href="classflow_1_1util_1_1Basic__blob.html#a719e5c04e4bdc65c31976fc385fd7f24" title="Returns the number of elements in the internally allocated buffer, which is 1 or more; or 0 if no buf...">capacity()</a>; rewrite <a class="el" href="classflow_1_1util_1_1Basic__blob.html" title="A hand-optimized and API-tweaked replacement for vector&lt;uint8_t&gt;, i.e., buffer of bytes inside an all...">Basic_blob</a> in terms of this <code>Tight_blob</code>. This simple container type has had some demand in practice, and <a class="el" href="classflow_1_1util_1_1Basic__blob.html" title="A hand-optimized and API-tweaked replacement for vector&lt;uint8_t&gt;, i.e., buffer of bytes inside an all...">Basic_blob</a> can and should be cleanly built on top of it (perhaps even as an IS-A subclass). </dd>
<dt>Member <a class="el" href="namespaceflow_1_1util.html#a9495b3e37e9d27bcc7767a4b6ce87ff4">flow::util::Lock_guard_non_recursive</a>  </dt>
<dd><a class="anchor" id="_todo000077"></a><a class="el" href="namespaceflow_1_1util.html#a9495b3e37e9d27bcc7767a4b6ce87ff4" title="(Deprecated given C++1x) Short-hand for advanced-capability RAII lock guard for Mutex_non_recursive m...">Lock_guard_non_recursive</a> is deprecated, now that C++1x made the more flexible <code>Lock_guard&lt;Mutex_non_recursive&gt;</code> possible. Remove it and all (outside) uses eventually.  </dd>
<dt>Member <a class="el" href="namespaceflow_1_1util.html#add56211dee74c212c19028f1ded2a785">flow::util::Lock_guard_noop_shared_non_recursive_ex</a>  </dt>
<dd><a class="anchor" id="_todo000082"></a><a class="el" href="namespaceflow_1_1util.html#add56211dee74c212c19028f1ded2a785" title="(Deprecated given C++1x) Equivalent to Lock_guard_shared_non_recursive_ex but applied to Mutex_noop_s...">Lock_guard_noop_shared_non_recursive_ex</a> is deprecated, now that C++1x made the more flexible <code>Lock_guard&lt;Mutex_noop_shared_non_recursive&gt;</code> possible. Remove it and all (outside) uses eventually.  </dd>
<dt>Member <a class="el" href="namespaceflow_1_1util.html#a9e5fae573be960434c4c9dacd48c9c11">flow::util::Lock_guard_noop_shared_non_recursive_sh</a>  </dt>
<dd><a class="anchor" id="_todo000081"></a><a class="el" href="namespaceflow_1_1util.html#a9e5fae573be960434c4c9dacd48c9c11" title="(Deprecated given C++1x) Equivalent to Lock_guard_shared_non_recursive_sh but applied to Mutex_noop_s...">Lock_guard_noop_shared_non_recursive_sh</a> is deprecated, now that C++1x made the more flexible <code>Shared_lock_guard&lt;Mutex_noop_shared_non_recursive&gt;</code> possible. Remove it and all (outside) uses eventually.  </dd>
<dt>Member <a class="el" href="namespaceflow_1_1util.html#a015b84cfa3076b8e75d16ec44a5514a3">flow::util::Lock_guard_recursive</a>  </dt>
<dd><a class="anchor" id="_todo000078"></a><a class="el" href="namespaceflow_1_1util.html#a015b84cfa3076b8e75d16ec44a5514a3" title="(Deprecated given C++1x) Short-hand for advanced-capability RAII lock guard for Mutex_recursive mutex...">Lock_guard_recursive</a> is deprecated, now that C++1x made the more flexible <code>Lock_guard&lt;Mutex_recursive&gt;</code> possible. Remove it and all (outside) uses eventually.  </dd>
<dt>Member <a class="el" href="namespaceflow_1_1util.html#a9df3cc2f3aec0c0353443b9d6c81e638">flow::util::Lock_guard_shared_non_recursive_ex</a>  </dt>
<dd><a class="anchor" id="_todo000080"></a><a class="el" href="namespaceflow_1_1util.html#a9df3cc2f3aec0c0353443b9d6c81e638" title="(Deprecated given C++1x) Short-hand for exclusive mode advanced-capability RAII lock guard for Mutex_...">Lock_guard_shared_non_recursive_ex</a> is deprecated, now that C++1x made the more flexible <code>Lock_guard&lt;Mutex_shared_non_recursive&gt;</code> possible. Remove it and all (outside) uses eventually.  </dd>
<dt>Member <a class="el" href="namespaceflow_1_1util.html#a689388b6eb7e760933d99381d65cacca">flow::util::Lock_guard_shared_non_recursive_sh</a>  </dt>
<dd><a class="anchor" id="_todo000079"></a><a class="el" href="namespaceflow_1_1util.html#a689388b6eb7e760933d99381d65cacca" title="(Deprecated given C++1x) Short-hand for shared mode advanced-capability RAII lock guard for Mutex_sha...">Lock_guard_shared_non_recursive_sh</a> is deprecated, now that C++1x made the more flexible <code>Shared_lock_guard&lt;Mutex_shared_non_recursive&gt;</code> possible. Remove it and all (outside) uses eventually.  </dd>
<dt>Member <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421">flow::util::Mutex_shared_non_recursive</a>  </dt>
<dd><a class="anchor" id="_todo000076"></a>Consider changing <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">util::Mutex_shared_non_recursive</a> from <code>boost::shared_mutex</code> to <code>std::shared_mutex</code>, as the former has a long-standing unresolved ticket about its impl being slow and/or outdated (as of Boost-1.80). However see also the note on <a class="el" href="namespaceflow_1_1util.html#a62b5ba6d6a549ac20e2c055e72bef421" title="Short-hand for non-reentrant, shared-or-exclusive mutex.">util::Mutex_shared_non_recursive</a> that explains why it might be best to avoid this type of mutex altogether in the first place (in most cases). </dd>
<dt>Class <a class="el" href="classflow_1_1util_1_1Rnd__gen__uniform__range.html">flow::util::Rnd_gen_uniform_range&lt; range_t &gt;</a>  </dt>
<dd><a class="anchor" id="_todo000066"></a><a class="el" href="classflow_1_1util_1_1Rnd__gen__uniform__range.html" title="Simple, non-thread-safe uniform-range random number generator.">Rnd_gen_uniform_range</a> and <a class="el" href="classflow_1_1util_1_1Rnd__gen__uniform__range__mt.html" title="Identical to Rnd_gen_uniform_range but safe for concurrent RNG given a single object.">Rnd_gen_uniform_range_mt</a>, on reflection, are very similar to <code>boost::random::random_number_generator</code>, and should be written to conform to it, so as to be usable in <code>std::random_shuffle()</code>, and also to gain its appealing extra features without losing any of the already-available simplicity. Note, however, that <code>std::random_shuffle()</code> is deprecated (and gone in C++17) in favor of <code>std::shuffle()</code>, which is available from C++11 on, and which works directly with a formal URNG such as <a class="el" href="classflow_1_1util_1_1Rnd__gen__uniform__range__base.html#a519fc83fd1c52a82618cd85f3a089668" title="The random generator engine; it is public for the reason explained in Usability section of the Rnd_ge...">Rnd_gen_uniform_range_base::Random_generator</a>. So this to-do is less about that and more about gaining those other features while being suitable for <code>random_shuffle()</code>, which some code does still use out there. </dd>
<dt>Member <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667">flow::util::schedule_task_from_now</a>  (<a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">log::Logger</a> *logger_ptr, const Fine_duration &amp;from_now, bool single_threaded, Task_engine *task_engine, Scheduled_task_handler &amp;&amp;task_body_moved)</dt>
<dd><p class="startdd"><a class="anchor" id="_todo000067"></a>We could eliminate <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> potential limitation versus <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> wherein each call constructs (internally) a new <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a>. A pool of <code>Timer</code>s can be internally maintained to implement this. This may or may not be worth the complexity, but if the API can remain identically simple while cleanly eliminating the one perf-related reason to choose <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">Timer</a> over this simpler facility, then that is a clean win from the API user's point of view. By comparison, other possible improvements mentioned <em>complicate</em> the API which makes them less attractive.</p>
<p class="enddd"><a class="anchor" id="_todo000068"></a><a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">schedule_task_from_now()</a> and surrounding API provides an easy way to schedule a thing into the future, but it is built on top of boost.asio <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">util::Timer</a> directly; an intermediate wrapper class around this would be quite useful in its own right so that all boost.asio features including its perf-friendliness would be retained along with eliminating its annoyances (around canceling-but-not-really and similar). Then scheduled_task_from_now() would be internally even simpler, while a non-annoying <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">util::Timer</a> would become available for more advanced use cases. echan may have such a class (in a different project) ready to adapt (called <code>Serial_task_timer</code>). I believe it internally uses integer "task ID" to distinguish between scheduled tasks issued in some chronological order, so that boost.asio firing a task after it has been canceled/pre-fired can be easily detected. </p>
</dd>
<dt>Member <a class="el" href="namespaceflow_1_1util.html#a09a032f8e1e77a3afc0b7df115a773e1">flow::util::setup_auto_cleanup</a>  (const Cleanup_func &amp;func)</dt>
<dd><a class="anchor" id="_todo000084"></a><a class="el" href="namespaceflow_1_1util.html#a09a032f8e1e77a3afc0b7df115a773e1" title="Provides a way to execute arbitrary (cleanup) code at the exit of the current block.">setup_auto_cleanup()</a> should take a function via move semantics. </dd>
<dt>Class <a class="el" href="classflow_1_1util_1_1Shared__ptr__alias__holder.html">flow::util::Shared_ptr_alias_holder&lt; Target_ptr, Const_target_ptr &gt;</a>  </dt>
<dd><p class="startdd"><a class="anchor" id="_todo000071"></a>Add example usage snippets in <a class="el" href="classflow_1_1util_1_1Shared__ptr__alias__holder.html" title="Convenience class template that endows the given subclass T with nested aliases Ptr and Const_ptr ali...">Shared_ptr_alias_holder</a> doc header, illustrating the pattern. </p>
<p class="interdd"><a class="anchor" id="_todo000070"></a><a class="el" href="classflow_1_1util_1_1Shared__ptr__alias__holder.html" title="Convenience class template that endows the given subclass T with nested aliases Ptr and Const_ptr ali...">flow::util::Shared_ptr_alias_holder</a>, such as it is, may well largely work for <code>unique_ptr</code> and other smart/fancy pointer types; should be generalized both in name (if possible) and capabilities (if not already the case). Could be just a matter of updating docs and renaming (deprecated-path alias may be required to avoid a breaking change); or not. Needs a bit of investigation to determine such details. (The author (ygoldfel) was conisderably less advanced when this was originally made versus the time of this writing... maybe a decade+? He meant well though.)</p>
<p class="enddd"><a class="anchor" id="_todo000069"></a><a class="el" href="classflow_1_1util_1_1Shared__ptr__alias__holder.html" title="Convenience class template that endows the given subclass T with nested aliases Ptr and Const_ptr ali...">flow::util::Shared_ptr_alias_holder</a> <code>Const_target_ptr</code> is deprecated and shall be always left at its default value in future code; eventually remove it entirely and hard-code the default value internally. </p>
</dd>
<dt>Class <a class="el" href="classflow_1_1util_1_1String__ostream.html">flow::util::String_ostream</a>  </dt>
<dd><a class="anchor" id="_todo000072"></a>Consider using <code>alt_sstream</code> in boost.format; it doesn't seem to have public documentation but isn't in a <code>detail</code> directory either. So that's interesting. It might have better performance than the implementation here (by being more "direct" probably). Then again it might not. </dd>
<dt>Member <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6">flow::util::Timer</a>  </dt>
<dd><p class="startdd"><a class="anchor" id="_todo000075"></a>Upgrade to newer Boost and keep testing timer resolutions on the above and other OS versions. Update: As of this writing we are on Boost 1.74 now. Needless to say, it is time to reassess the above, as it has been years since 1.50 &ndash; and we had been on 1.63 and 1.66 for long period of time, let alone 1.74. Update: No changes with Boost 1.75, the newest version as of this writing.</p>
<p class="enddd"><a class="anchor" id="_todo000074"></a>Test macOS timer fidelity. </p>
</dd>
<dt>Member <a class="el" href="namespaceflow_1_1util.html#a0f681afaf67a0f917cf43a7ae893a015">flow::util::to_mbit_per_sec</a>  (N_items items_per_time, size_t bits_per_item=8)</dt>
<dd><a class="anchor" id="_todo000083"></a>boost.unit "feels" like it would do this for us in some amazingly pithy and just-as-fast way. Because Boost.  </dd>
<dt>Member <a class="el" href="log_8hpp.html#a626c7dc4d3b4dc0b32a8aac8624d66bc">FLOW_LOG_WARNING</a>  (ARG_stream_fragment)</dt>
<dd><a class="anchor" id="_todo000022"></a>We can avoid using macros for this and similar APIs by requiring the user to use commas instead of the usual <code>&lt;&lt;</code> and by implementing this as a variadic function template (C++11 feature).</dd>
</dl>
</div></div><!-- contents -->
</div><!-- PageDoc -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Mar 28 2025 22:55:32 for Flow by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
